/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Homework5;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicListUI.*;

/**
 *
 * @author Jakim
 */

public class ListDemo extends JFrame {
    private DefaultListModel modelSource;
    private DefaultListModel modelDestination;

    // public properties
    public JPanel panelLeft;
    public JPanel panelCenter;
    public JPanel panelRight;
    public JTextField txtFiller;
    public JList lstSource;
    public JList lstDestination;
    public JButton btnAdd;
    public JButton btnLoad;
    public JButton btnUnload;
    public JButton btnUp;
    public JButton btnDown;
    public JLabel lblCountSource;
    public JLabel lblCountDestination;

    //private methods
    private void addNewItemToSource() {
                String strToAdd = txtFiller.getText();
                txtFiller.setText("");
                modelSource.addElement(strToAdd);
            }

    // constructors
    public ListDemo(){
        super("ListDemo");
        this.setLayout(new BorderLayout(10, 10));

        // Application ListDemo left side.
        this.modelSource = new DefaultListModel();
        this.modelSource.addElement("Ракия");
        this.modelSource.addElement("Джин");
        this.modelSource.addElement("Мастика");
        this.modelSource.addElement("Водка");
        this.modelSource.addElement("Шлйокавица");
        this.modelSource.addListDataListener(new ListDataListener(){

            @Override
            public void intervalAdded(ListDataEvent e) {
                lblCountSource.setText(String.valueOf(modelSource.size()));
            }

            @Override
            public void intervalRemoved(ListDataEvent e) {
                lblCountSource.setText(String.valueOf(modelSource.size()));
            }

            @Override
            public void contentsChanged(ListDataEvent e) {
                lblCountSource.setText(String.valueOf(modelSource.size()));
            }

        });

        this.lstSource = new JList(modelSource);
        this.lstSource.setMaximumSize(new DimensionUIResource(200, 300));
        this.lstSource.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2){
                    Object item = lstSource.getSelectedValue();
                    modelDestination.addElement(item);
                    modelSource.removeElement(item);
                }
            }
        });

        JScrollPane scrollPanrSource = new JScrollPane();
        scrollPanrSource.add(this.lstSource);
         
        this.lblCountSource = new JLabel(String.valueOf(this.modelSource.size()));

        this.txtFiller = new JTextField("");
        this.txtFiller.setMaximumSize(new DimensionUIResource(140, 25));
        this.txtFiller.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
               addNewItemToSource();
            }
        });

        this.btnAdd = new JButton("Add");
        this.btnAdd.setMaximumSize(new DimensionUIResource(60, 25));
        this.btnAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                addNewItemToSource();
            }
        });

        JPanel panelAddItemToSource = new JPanel();
        panelAddItemToSource.setLayout(new BoxLayout(panelAddItemToSource, BoxLayout.X_AXIS));
        panelAddItemToSource.setMaximumSize(new DimensionUIResource(200, 30));
        panelAddItemToSource.add(this.txtFiller);
        panelAddItemToSource.add(this.btnAdd);

        this.panelLeft = new JPanel();
        this.panelLeft.setLayout(new BoxLayout(this.panelLeft, BoxLayout.Y_AXIS));
        this.panelLeft.add(panelAddItemToSource);
        this.panelLeft.add(this.lstSource);
        this.panelLeft.add(this.lblCountSource);
        this.panelLeft.setPreferredSize(new DimensionUIResource(200, 400));

        // Application ListDemo center side.
        this.btnLoad = new JButton(">");
        this.btnLoad.setMaximumSize(new DimensionUIResource(50, 70));
        this.btnLoad.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                Object[] items = lstSource.getSelectedValues();
                for (Object item : items){
                    modelDestination.addElement(item);
                    modelSource.removeElement(item);
                }
            }
        });

        this.btnUnload = new JButton("<");      
        this.btnUnload.setMaximumSize(new DimensionUIResource(50, 70));
        this.btnUnload.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object[] items = lstDestination.getSelectedValues();
                for (Object item : items){
                    modelSource.addElement(item);
                    modelDestination.removeElement(item);
                }
            }
        });

        this.panelCenter = new JPanel();
        this.panelCenter.setLayout(new BoxLayout(this.panelCenter, BoxLayout.Y_AXIS));
        this.panelCenter.add(this.btnLoad);
        this.panelCenter.add(this.btnUnload);

        this.btnUnload.setLocation(new Point(50, 200));

        // Application Right side.
        this.modelDestination = new DefaultListModel();
        this.modelDestination.addListDataListener(new ListDataListener(){

            @Override
            public void intervalAdded(ListDataEvent e) {
                lblCountDestination.setText(String.valueOf(modelDestination.size()));
            }

            @Override
            public void intervalRemoved(ListDataEvent e) {
                lblCountDestination.setText(String.valueOf(modelDestination.size()));
            }

            @Override
            public void contentsChanged(ListDataEvent e) {
                lblCountDestination.setText(String.valueOf(modelDestination.size()));
            }

        });

        this.btnUp = new JButton("Up");
        this.btnUp.setMaximumSize(new DimensionUIResource(70, 25));
        this.btnUp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int prevElementIndex = 0;
                int currentSelectedIndex = 0;
                int[] selectedIndexes = lstDestination.getSelectedIndices();
                int[] newSelectedIndexes = new int[selectedIndexes.length];

                for (int index : selectedIndexes) {
                    if (index > prevElementIndex &&
                        !(lstDestination.isSelectedIndex(index - 1))) {
                        Object item = modelDestination.remove(index);
                        modelDestination.add(index - 1, item);
                        prevElementIndex = index - 1;
                        newSelectedIndexes[currentSelectedIndex++] = prevElementIndex;
                    }else{
                        newSelectedIndexes[currentSelectedIndex++] = index;
                    }
                }

                lstDestination.setSelectedIndices(newSelectedIndexes);
            }
        });

        this.btnDown = new JButton("Down");
        this.btnDown.setMaximumSize(new DimensionUIResource(70, 25));
        this.btnDown.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int nextElementIndex = lstDestination.getLastVisibleIndex();
                int currentSelectedIndex = 0;
                int[] selectedIndexes = lstDestination.getSelectedIndices();
                int[] newSelectedIndexes = new int[selectedIndexes.length];

                for (int i = selectedIndexes.length - 1; i >= 0  ; i--) {
                    int index = selectedIndexes[i];
                    if (index < nextElementIndex &&
                        !(lstDestination.isSelectedIndex(index + 1))) {
                        Object item = modelDestination.remove(index);
                        modelDestination.add(index + 1, item);
                        nextElementIndex = index + 1;
                        newSelectedIndexes[currentSelectedIndex++] = nextElementIndex;
                    }else{
                        newSelectedIndexes[currentSelectedIndex++] = index;
                    }
                }

                lstDestination.setSelectedIndices(newSelectedIndexes);
            }
        });

        JPanel panelUpDown = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
        panelUpDown.setMaximumSize(new DimensionUIResource(200, 30));
        panelUpDown.add(this.btnUp);
        panelUpDown.add(this.btnDown);

        JScrollPane scrollDestination = new JScrollPane();
        this.lstDestination = new JList(this.modelDestination);
        this.lstDestination.setMaximumSize(new DimensionUIResource(200, 300));
        this.lstDestination.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2){
                    Object item = lstDestination.getSelectedValue();
                    modelSource.addElement(item);
                    modelDestination.removeElement(item);
                }
            }
        });
        scrollDestination.add(this.lstDestination);

        this.lblCountDestination = new JLabel("0");

        this.panelRight = new JPanel();
        this.panelRight.setLayout(new BoxLayout(this.panelRight, BoxLayout.Y_AXIS));
        this.panelRight.add(panelUpDown);
        this.panelRight.add(this.lstDestination);
        this.panelRight.add(this.lblCountDestination);

        this.add(this.panelLeft, BorderLayout.WEST);
        this.add(this.panelCenter, BorderLayout.CENTER);
        this.add(this.panelRight, BorderLayout.EAST);
        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        this.pack();
        this.setMinimumSize(this.getSize());
        this.setMaximumSize(this.getPreferredSize());
        this.setVisible(true);
    }

    public static void main(String[] args){
        new ListDemo();
    }
}